#include <jni.h>
#include <string>
#include "bean/Student.h"
#include "log.h"
#include "bean/Worker.h"



void workerTOWork(std::Worker worker) {
    LOGI("工人姓名为：%s 年龄：%d", worker.name.c_str() , worker.age);
}

void workerTOWork2(std::Worker *worker) {
    LOGI("工人姓名为：%s 年龄：%d", worker->name.c_str() , worker->age);
}

void workerTOWork3(const std::Worker worker) {
    // worker.name = "sdf"; 错误
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_sdp_myapplication_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";


    // 不带参数的构造函数
    Student student;
    int age1 = student.getAge();
    LOGI("get student age %d",age1);


    Student *student1 = new Student();
    int age2 = student1->getAge();
    LOGI("get student age %d",age2);

    // 释放资源
    delete student1;

    // 有参的构造函数
    int age = 900;
    std::string name = "axeCheneeee";

    std::string hobby[5] = {"one","two","three","four","five"};

    std::list<int> allint = {1,2,4,3,4,3,34,89};

    std::map<int, std::string> sourceMap = {{1, "one"}, {2, "two"}, {3, "three"}};

    Student student2(age, name, hobby, allint, sourceMap);

    LOGI("get student age %d",student2.getAge());

    LOGI("get student name %s", student2.getName().c_str());

    for (int i = 0; i < student2.getHobby()->size(); ++i) {
        LOGI("get all ini index, %s", student2.getHobby()[i].c_str());
    }

    for (int elem : student2.getAllint()) {
        // 遍历访问所有元素
        LOGI("get all ini index, %d", elem);
    }

    for (const auto& pair : student2.getAllSocre()) {
        LOGI("socre key %d, socre value %s", pair.first, pair.second.c_str());
    }

    std::vector<std::string> sourceArray = {"string1", "string2", "string3"};
    student2.setOtherStr(sourceArray);

    student2.addOtherStr("990");

    for (const auto& str : student2.getOtherStr()) {
        LOGI("get other string, %s", str.c_str());
    }

    // 测试拷贝函数
    Student copyStudent(student2);


    LOGI("测试拷贝函数");

    LOGI("copyStudent get student age %d",copyStudent.getAge());

    LOGI("copyStudent get student name %s", copyStudent.getName().c_str());

    for (int i = 0; i < copyStudent.getHobby()->size(); ++i) {
        LOGI("copyStudent get all ini index, %s", copyStudent.getHobby()[i].c_str());
    }

    for (int elem : copyStudent.getAllint()) {
        // 遍历访问所有元素
        LOGI("copyStudent get all ini index, %d", elem);
    }

    for (const auto& pair : copyStudent.getAllSocre()) {
        LOGI("copyStudent socre key %d, socre value %s", pair.first, pair.second.c_str());
    }

    for (const auto& str : copyStudent.getOtherStr()) {
        LOGI("copyStudent get other string, %s", str.c_str());
    }


    //// ------------------------ struct --------------------------- 以下是结构体的代码

    // 简单结构体的使用
    std::Worker work1;
    work1.name = "张三";
    work1.age = 18;
    LOGI("工人姓名为：%s 年龄：%d", work1.name.c_str() , work1.age);

    // 结构体数组
    struct std::Worker workerAar[3] = {
            {"张1",12},
            {"张2",14},
            {"张3",15},
    };
    // 遍历结构体数组
    for (int i = 0; i < sizeof(workerAar)/sizeof(workerAar[0]) ; i++) {
        LOGI("工人姓名为：%s 年龄：%d", workerAar[i].name.c_str() , workerAar[i].age);
    }

    // 结构体指针
    std::Worker worker2 = {"哈哈",12};
    std::Worker *p = &worker2;
    LOGI("工人姓名为：%s 年龄：%d", p->name.c_str() , p->age);

    // 使用new来创建结构体 (注意delete)
    std::Worker *worker3 = new std::Worker();
    worker3->name = "莱登";
    worker3->age = 90;
    LOGI("工人姓名为：%s 年龄：%d", worker3->name.c_str() , worker3->age);

    delete worker3;

    // 结构体嵌套结构体
    std::WorkerLead workerLead;
    workerLead.type = 1;
    workerLead.worker.name = "鸡哥";
    workerLead.worker.age = 13;

    workerLead.worker = work1;

    std::Worker *worker22 = new std::Worker();
    worker22->name = "鸡毛";
    worker22->age = 78;
    workerLead.worker2 = worker22;

    LOGI("工人姓名为：%s 年龄：%d 类型：%d", workerLead.worker.name.c_str() , workerLead.worker.age, workerLead.type);
    LOGI("工人2姓名为：%s 年龄：%d 类型：%d", workerLead.worker2->name.c_str() , workerLead.worker2->age, workerLead.type);

    delete worker22;

    std::WorkerLead *pLead = &workerLead;
    pLead->worker.name = "狗哥";
    LOGI("工人姓名为：%s 年龄：%d 类型：%d", pLead->worker.name.c_str() , pLead->worker.age, pLead->type);


    // 结构体作为参数传递
    workerTOWork(work1);
    workerTOWork2(&work1);


    std::workTest ww = {
        "ww",
        12,
    };
    LOGI("工人姓名为：%s 年龄：%d", ww.name.c_str() , ww.age);

    std::workTest ww2;
    ww2.age = 78;
    ww2.name = "ww2";

    LOGI("工人姓名为：%s 年龄：%d", ww2.name.c_str() , ww2.age);


    std::t_worker_test2 tWorkerTest2 = {
            "gogo",
            12,
    };
    LOGI("工人姓名为：%s 年龄：%d", tWorkerTest2.name.c_str() , tWorkerTest2.age);

    delete worker22;


    return env->NewStringUTF(hello.c_str());
}